[iOS] ネットワーク接続状態の検出
1 はじめに
ネットワーク接続中の時のみ使用可能な機能では、切断中にUIをDisabledにしておきたいと言うようなニーズがあると思います。
今回は、このような場合に必要となる、ネットワーク接続状態の取得方法です。
ネットワークの接続状態は、SystemConfigration.frameworkを使用して実装しますが、これをラップしたライブラリであるReachabilityが、Appleから提供されており、通常は、これを利用するのが簡単です。
2 導入方法
(1) CocoaPods
Reachabilityは、CocoaPodsでインストール可能です。
pod 'Reachability'
導入後は、下記のヘッダをインポートすることで利用可能になります。
#import "Reachability.h"
SystemConfigration.frameworkは、自動的に追加されます。
(2) サンプルコード
Reachabilityは、サンプルコードとして、下記に置かれています。
Guide and Sample Code Reachability
ここから、Reachability.hとReachability.mを取得して、プロジェクトに追加することでも、利用が可能です。
3 利用方法
(1) 到達可否
Reachabilityでは、以下の3種類で、到達可否を取得できます。
// ホスト名を指定して、到達の可能性を取得します + (instancetype)reachabilityWithHostName:(NSString *)hostName; // IPアドレスを指定して、到達の可能性を取得します + (instancetype)reachabilityWithAddress:(const struct sockaddr *)hostAddress; // 0.0.0.0への到達の可能性を取得します + (instancetype)reachabilityForInternetConnection;
(2) 接続の種類
先のメソッドの戻り値としてReachabilityのインスタンスを受け取り、currentReachabilityStatusプロパティで接続の種類を確認することができます。
下記は、その一例です。
NSString *hostName = @"www.gogle.com"; Reachability *reachablity = [Reachability reachabilityWithHostName:hostName]; NetworkStatus status = [reachablity currentReachabilityStatus]; switch (status) { case NotReachable: // 接続不能 break; case ReachableViaWWAN: // WWANによる接続 break; case ReachableViaWiFi: // Wi-Fiによる接続 break; default: NSLog(@"%zd",status); break; }
(3) 接続確立
ダイアルアップや、オンデマンドVPNなど、接続の確立が必要であるかどうかの取得
- (BOOL)connectionRequired;
(4) 通知
Reachabilityでは、接続状態の変化で通知を受け取ることが可能です。
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reachabilityChanged:) name:kReachabilityChangedNotification object:nil];
そして、パラメータで、現在状態を保持したReachabilityを受け取ることができます。
- (void) reachabilityChanged:(NSNotification *)note { Reachability* currentReachability = [note object]; }
また、Notificationの中断及び再開も可能です。
- (BOOL)startNotifier; - (void)stopNotifier;
4 注意事項など
(1) reachabilityForLocalWiFiは削除されています
Wi-Fiの接続状況を確認するために、reachabilityForLocalWiFiの使用例を紹介したページが幾つか検索されますが、現在、Bonjourの使用を前提に設計されていた、reachabilityForLocalWiFiは、削除されており利用できません。
(2) IPv6
2016/05/05以降、IPv6に完全対応しています。
reachabilityWithAddress:のパラメータ、struct sockaddr *へは、sockaddr_in6 及び、sockaddr_inの両方が使用可能です。
(3) DNS
reachabilityWithHostName:で、ホスト名を指定して、到達可否を判断する場合、その名前解決が必要ですが、これに時間がかかる場合、名前解決が完了するまで、NotReachableになることに注意が必要です。
(4) 機内モード
機内モードをONにすると、一旦、Wi-FiがOFFになりますが、機内モードONの状態でWi-FiをONにすることは可能です。
また、Reachabilityで機内モードを検出する事はできません。
アプリで機内モードを検出するには、info.plistにUIRequiresPersistentWiFiキーを追加してYESに設定します。
こうすることで、機内モードになった時に、下記のダイアログを表示させることができます。
5 最後に
今回は、Reachabilityの利用方法について纏めてみました。 アプリの要求に応じて、到達可否のメソッドを使い分けないと、予想外な動作になってしまう事に注意が必要だと感じました。